﻿/**
 * 定义Logger
 *
 * @file Logger.h
 * @author Song
 * @date 2011-9-18
 *
 */


#pragma once

#include <vector>
#include <algorithm>

#include "t_string.h"
#include "appender.h"
#include "log_catagory.h"
#include "log_item.h"

/// @defgroup logger
/// @{
/// @defgourp logger_example 使用示例
/// @}

namespace log4lite {
	
	/// 日志类
	class Logger
	{
		typedef std::vector<AppenderPtr> AppenderList;
	
	public:
		Logger()
			: _catagory(ALL_LOG_CATAGORY)
		{
			//
		}

		~Logger()
		{
			//
		}

	public:

		/// @name 输出器 
		/// @{

		/// 添加
		void addAppender(AppenderPtr newAppender)
		{
			if (newAppender == NULL) {
				tcout << T_TEXT("Tried to add NULL appender\n");
			}

			AppenderList::iterator it = std::find(_appenderList.begin(), _appenderList.end(), newAppender);
			if(it == _appenderList.end()) {
				_appenderList.push_back(newAppender);
			}
		}
		/// 删除
		void removeAppender(AppenderPtr appender)
		{
			if(appender == NULL) {
				tcout << T_TEXT("Tried to remove NULL appender\n");
				return;
			}

			AppenderList::iterator it = std::find(_appenderList.begin(), _appenderList.end(), appender);
			if(it != _appenderList.end()) {
				_appenderList.erase(it);
			}
		}
		/// @}

		bool isEnabledFor(LogCatagory lc)
		{
			if (_catagory & lc) {
				return true;
			} else {
				return false;
			}
		}

		/// 判断了日志分类
		void log(LogCatagory lc, tstring message, const char* filename, int lineno)
		{
			if ( isEnabledFor(lc) ) {
				forcedLog(lc, message, filename, lineno);
			} else {
		//		throw std::runtime_error("No valid LogCatagory found");
			}
		}

		/// 未判断日志分类
		void forcedLog(LogCatagory lc, tstring message, const char* filename, int lineno)
		{
			callAppenders(LogItem(lc, message, filename, lineno));
		}
		
		/// 指定欲输出日志的分类
		/// 默认输出所有分类
		void setOutputCatagory(LogCatagory lc)
		{
			this->_catagory = lc;
		}


	private:
		void callAppenders(const LogItem& item) const
		{
			for(AppenderList::const_iterator it=_appenderList.begin(); it!=_appenderList.end(); ++it) {
				(*it)->doAppend(item);
			}
		}

	private:
		LogCatagory _catagory;
		AppenderList _appenderList;
	};

} // namespace
